// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "MotionSubtitlesLayerBase.h"
#include "TextInfos.h"
#include "MotionSubtitlesTextLayer.generated.h"

/**
 * 
 */
UCLASS(ClassGroup=(MotionSubtitles), meta=(BlueprintSpawnableComponent))
class MOTIONSUBTITLES_API UMotionSubtitlesTextLayer : public UMotionSubtitlesLayerBase
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=MotionSubtitles)
	TArray<FSubtitleContent> Contents;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles)
	FString FontName;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles)
	int32 FontSize = 4096;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles,meta=(ClampMin=0, ClampMax=1))
	float FontScale = 1;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles)
	FLinearColor FillingColor;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles)
	FLinearColor OutlineColor;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles)
	FLinearColor ShadowColor;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles)
	FLinearColor MarqueeColor;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles, meta=(ClampMin=0, ClampMax=10))
	float OutlineWidth = 0;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles, meta=(ClampMin=-1, ClampMax=1))
	float ShadowBiasX = 0;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles, meta=(ClampMin=-1, ClampMax=1))
	float ShadowBiasY = 0;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles, Interp, meta=(ClampMin=0, ClampMax=1))
	float Alpha = 1.0;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles, Interp, meta=(ClampMin=0, ClampMax=1))
	float Blur = 0.0;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles, Interp, meta=(ClampMin=0, ClampMax=2))
	float Dissolve = 2.0;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category=MotionSubtitles)
	FTextLayoutInfo TextLayoutInfo;

	UPROPERTY(EditDefaultsOnly)
	TObjectPtr<UStaticMesh> PlaneStaticMesh;

	UPROPERTY(EditDefaultsOnly)
	TObjectPtr<UMaterialInterface> StylizedTextMaterial;

	UPROPERTY(VisibleInstanceOnly)
	TArray<TObjectPtr<UStaticMeshComponent>> TextPlanes;

	TArray<FVector> TextOriginLocations;
	TArray<FVector> TextOriginScales;

public:
	UMotionSubtitlesTextLayer();

	virtual void Init(const FUint32Vector2& ViewSize) override;

	UFUNCTION(BlueprintCallable)
	virtual void Show(const FSubtitleParams& Params) override;

	UFUNCTION(BlueprintCallable)
	virtual void Hide() override;

	virtual void Exit() override;

public:
	virtual void DoScale(const EAnimTarget AnimTarget, const int32 ElementId, const float Value) override;
	virtual void DoTranslate(const EAnimTarget AnimTarget, const int32 ElementId,const FVector Value) override;
	virtual void DoFade(const EAnimTarget AnimTarget, const int32 ElementId,const float Value) override;
	virtual void DoDissolve(const EAnimTarget AnimTarget, const int32 ElementId,const float Value) override;
	virtual void DoMarquee(const EAnimTarget AnimTarget,const EAnimDirection Direction, const int32 ElementId, const float Value) override;
	virtual void CaptureStatus() override;
	virtual int32 ElementCount() override;
private:
	bool GenerateSdf(const FString& SingleChar, const FString& FontPath, FTextFontInfo& FontInfo) const;

	bool GenerateMaterial(const FTextFontInfo& FontInfo, UMaterialInstanceDynamic*& MaterialInstance);

	bool GenerateTextMesh(UStaticMesh* StaticMesh, UMaterialInstanceDynamic* Material,
	                      UStaticMeshComponent*& StaticMeshComponent);

	bool GenerateTextPlanes(const FSubtitleContent& Content,const FString& DefaultFont,TArray<FTextFontInfo>& Infos);

	void LayoutText(TQueue<FSubtitleLineParams>& Lines) const;
	
	void LayoutText(const TArray<FTextFontInfo>& Infos,const FVector2f& Offset) const;

	bool FindTtfFile(const FString& Font,FString& RealPath);

	bool FindTextStyle(const TArray<FTextStyle>& Styles,const int32 CharIndex,FTextStyle*& Style);

	void OverrideTtfFile(const FTextStyle* Style,FString& Font);

	void OverrideFillingColor(const FTextStyle* Style,FTextFontInfo& FontInfo);

	void OverrideOutlineColor(const FTextStyle* Style,FTextFontInfo& FontInfo);

	void OverrideEnhance(const FTextStyle* Style,FTextFontInfo& FontInfo);
};
